﻿using System.ComponentModel;
using DetiInteract.Control.CommHandlers;
using System.Globalization;

namespace DetiInteract.Control
{
    public sealed class Controller
    {
        #region Fields

        /// <summary>
        /// Handles all Bluetooth communication
        /// </summary>
        BluetoothCommHandler btHandler = new BluetoothCommHandler();

		#endregion

		#region Events
		/// <summary>
        /// Events used to notify the UI thread of communication from the btHandler
        /// </summary>
        public event ProgressChangedEventHandler Tap;
        public event ProgressChangedEventHandler LongPress;
        public event ProgressChangedEventHandler Scroll;
        public event ProgressChangedEventHandler Fling;
        public event ProgressChangedEventHandler Rotation;
		public event ProgressChangedEventHandler Zoom;
        public event ProgressChangedEventHandler Connected;
        public event ProgressChangedEventHandler Disconnected;

        #endregion

		#region Initialization
		/// <summary>
        /// Constructor.
        /// Sets up the event handler for the btHandler.
        /// </summary>
        public Controller()
        {
            btHandler.Gesture += new ProgressChangedEventHandler(btHandler_Gesture);
        }

        /// <summary>
        /// Starts the btHandler in listening mode.
        /// </summary>
        public void Init()
        {
            if (!btHandler.bListening)
                btHandler.Listen();
        }
		#endregion

        #region Gesture Events
        
		/// <summary>
        /// Handles a gesture sent by the btHandler. Triggers the appropriate event
        /// to notify the UI thread.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btHandler_Gesture(object sender, ProgressChangedEventArgs e)
        {
            string strGesture = e.UserState as string;

			// The values in the gesture string come separated by ":"
            string[] args = strGesture.Split(':');

            switch (args[0])
            {
				// device connected
                case "Connected":
                    SetConnected(new ProgressChangedEventArgs(0,args[1]));
                    break;

                // stop / device disconnected
                case "00":
                    SetDisconnected(new ProgressChangedEventArgs(0,null));
                    break;

                // tap
                case "01":
                    SetTap(new ProgressChangedEventArgs(0, null));
                    break;

                // long press
                case "03":
                    SetLongPress(new ProgressChangedEventArgs(0, null));
                    break;

                // scroll
                case "05":
                    SetScroll(new ProgressChangedEventArgs(0, new GestureData.ScrollData(args[1], args[2])));
                    break;

                // fling
                case "04":
                    SetFling(new ProgressChangedEventArgs(0, new GestureData.ScrollData(args[1], args[2])));
                    break;

                // rotate
                case "06":
                    SetRotation(new ProgressChangedEventArgs(0, new GestureData.RotationData(args[1], args[2], args[3])));
                    break;

				// zoom
				case "07":
					CultureInfo ci = new CultureInfo("en-US");
					float scale = float.Parse(args[1], ci);
					SetZoom(new ProgressChangedEventArgs(0, scale));
					break;

                // default, unreacognized data
                default:
                    break;
            }
        }
		
		/// <summary>
        /// Triggers the Connected event
        /// </summary>
        /// <param name="e"></param>
        private void SetConnected(ProgressChangedEventArgs e)
        {
            if (Connected != null) Connected(this, e);
        }

        /// <summary>
        /// Triggers the Disconnected event
        /// </summary>
        /// <param name="e"></param>
        private void SetDisconnected(ProgressChangedEventArgs e)
        {
            if (Disconnected != null) Disconnected(this, e);
        }

        /// <summary>
        /// Triggers the Tap event
        /// </summary>
        /// <param name="e"></param>
        private void SetTap(ProgressChangedEventArgs e)
        {
            if (Tap != null) Tap(this, e);
        }

        /// <summary>
        /// Triggers the LongPress event
        /// </summary>
        /// <param name="e"></param>
        private void SetLongPress(ProgressChangedEventArgs e)
        {
            if (LongPress != null) LongPress(this, e);
        }

        /// <summary>
        /// Triggers the Scroll event
        /// </summary>
        /// <param name="e"></param>
        private void SetScroll(ProgressChangedEventArgs e)
        {
            if (Scroll != null) Scroll(this, e);
        }

        /// <summary>
        /// Triggers the Fling event
        /// </summary>
        /// <param name="e"></param>
        private void SetFling(ProgressChangedEventArgs e)
        {
            if (Fling != null) Fling(this, e);
        }

		/// <summary>
		/// Triggers the Rotation event
		/// </summary>
		/// <param name="e"></param>
		private void SetRotation(ProgressChangedEventArgs e)
		{
			if (Rotation != null) Rotation(this, e);
		}

		/// <summary>
		/// Triggers the Zoom event
		/// </summary>
		/// <param name="e"></param>
		private void SetZoom(ProgressChangedEventArgs e)
		{
			if (Zoom != null) Zoom(this, e);
		}
        #endregion
    }
}
